#include "driver.h"

status driver::init_driver(){
    this->fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);

    if (this->fd < 0){
        std::cerr << "Error : open" << std::endl;
        return 0;
    }

    if(ioctl(this->fd, UI_SET_EVBIT, EV_KEY) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;}
    if(ioctl(this->fd, UI_SET_EVBIT, EV_ABS) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;}

    if(ioctl(this->fd, UI_SET_KEYBIT, BTN_LEFT) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} // A funciona
    if(ioctl(this->fd, UI_SET_KEYBIT, BTN_RIGHT) < 0) { std::cerr << "error: ioctl" << std::endl; return 0;} // B funciona
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_POWER) < 0) { std::cerr << "error: ioctl" << std::endl; return 0;} // power
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_VOLUMEDOWN) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} //2
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_VOLUMEUP) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} // 1
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_PREVIOUSSONG) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} // - funciona
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_NEXTSONG) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} // + funciona
    if(ioctl(this->fd, UI_SET_KEYBIT, KEY_PLAYPAUSE) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;} // + presionado

    if(ioctl(this->fd, UI_SET_ABSBIT, ABS_Y) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;}
    if(ioctl(this->fd, UI_SET_ABSBIT, ABS_X) < 0){ std::cerr << "error: ioctl" << std::endl; return 0;}


    memset(&this->udev, 0, sizeof(this->udev));
    strncpy(this->udev.name, "Wiimote", UINPUT_MAX_NAME_SIZE-1);
    udev.id.bustype = BUS_BLUETOOTH;
    udev.id.vendor = 0x01;
    udev.id.product = 0x01;
    udev.id.version = 1;
    //
    udev.absmin[ABS_X] = 0;
    udev.absmax[ABS_X] = 1920;
    udev.absmin[ABS_Y] = 0;
    udev.absmax[ABS_Y] = 1080;

    if(write(fd, &udev, sizeof(udev)) < 0){ std::cerr << "error: write" << std::endl; return 0;}
    if(ioctl(fd, UI_DEV_CREATE) < 0){ std::cerr << "error: create" << std::endl; return 0;}

    return 1;
}

status driver::destroy_driver(){
    if(ioctl(this->fd, UI_DEV_DESTROY) < 0) return 0;
    return 1;
}



status driver::system_poll(){
    while(1){
        if(wiiuse_poll(this->wmte.wm, this->wmte.num)){
            for(int x=0; x< this->wmte.num; x++){
                switch(this->wmte.wm[x]->event){
                    case WIIUSE_EVENT:
                        handle_event(this->wmte.wm[x]);
                        break;
                    case WIIUSE_DISCONNECT:
                    case WIIUSE_UNEXPECTED_DISCONNECT:
                        return 0;
                    case WIIUSE_NONE: //if WIIUSE_NONE, call the status of wiimote
                        wiiuse_status(this->wmte.wm[x]);
                        break; //(continue?)
                }
            }
        }
    }
}

driver::driver(){
    if(!init_driver()) std::cerr << "error: creating driver" << std::endl;
}

driver::~driver(){
    if(!destroy_driver()) std::cerr << "error: destroying driver" << std::endl;
}
